unit oEditorLLManager;

{
	created   26.3.2010
	author   	Miroslav Mintal
	purpose
}

interface

uses
   Windows, ComCtrls, Types, SysUtils, Dialogs, oManager, oProcessItem,
   OProcessObjectConstants, oFrameLL, oFormLL, oProject, oLevel, Vector,
   Generics.Collections, oLogicalEntity, oPolygon, Obstacle, oCoordinates,
   oFrameScene, oPhysicalEntity, oEntityTypeConstants, Path;

type
  ELLManager = class(Exception)
  end;

  TEditorLLManager = class(TManager)
    private
      aName: string;
      aFrame: TFrameLL;
      aEntityId : integer;
      aEditorFrame: Tfeditor;
      aEditing : boolean;
      procedure addPhysicalLayers(paMap : TList<TMapping>);
      procedure setComponent(paFrame: TFrameLL);
    public
      constructor create(paMaster: TManager);

      function ProcessObject(paItem: TProcessItem):TProcessItem; override;
  end;

implementation

uses
  oProcessObjects;

{ TTreeManager }

function TEditorLLManager.ProcessObject(paItem: TProcessItem): TProcessItem;
var
   suc, ret : Boolean;
   form: TformLL;
   item : TPRocessitem;
   list : TProcessingList;
   level : TLevel;
   value : Tinteger;
   log : TLogicalEntity;
   phs : TPhysicalEntity;
   obst: TPolygonObstacle;
   pp: TPathPoint;
   j: Integer;
   name : string;
   coord : TCoordinates;
begin
    ret := false;
    suc := false;
    list := nil;

    if paItem.Data <> nil then
     if paItem.Data is TProcessingLevel then
        level := TProcessingLevel(paItem.Data).Level
     else
      if paItem.Data is TInteger then
        value := TInteger(paItem.Data);

    case paItem.Code of
      PO_EDITOR_LL_NEW_FRM : begin
        form := TformLL.Create(nil);
        setComponent(form.frame AS TFrameLL);
        aFrame.Manager := Self;
        form.Show;
        aEditing := false;
        name := 'log0';
        aEditorFrame := form.TfEditor1;
        aEditorFrame.Manager := self;
        aEditorFrame.LevelSize := oLevel.DEFAULT_SECTOR_SIZE * oLevel.DEFAULT_ROW_COUNT;
        aFrame.txtName.Enabled := true;

        aMaster.ProcessObject(TProcessItem.create(PO_SCENE_UNLOAD_LOG_LAYER, nil));
        aMaster.ProcessObject(TProcessItem.create(PO_PROJECT_INSERT_LOG_LAYER, TString.Create(name)));
        aMaster.ProcessObject(TProcessItem.create(PO_SCENE_GET_ID, TInteger.Create(aEntityId)));
        item := aMaster.ProcessObject(TProcessItem.create(PO_SCENE_GET_ACTUAL_LEVEL, nil));
        if item.Data <> nil then
         begin
          level := TProcessingLevel(item.Data).Level;
          if level <> nil then
           begin
            aEditorFrame.LevelSize := level.SizeX;
            form.Init;
            ProcessObject(TProcessItem.create(PO_EDITOR_LL_SET_LEVEL, TProcessingLevel.Create(TProcessingLevel(item.Data).Level)));
            item := aMaster.ProcessObject(TProcessItem.create(PO_SCENE_GET_ID, nil));
            aMaster.ProcessObject(TProcessItem.create(PO_EDITOR_LL_SET_ID, TInteger.Create(TInteger(item.Data).Integer_)));
           end
          else
            raise ELLManager.Create('Error on level load');
         end;
        Master.ProcessObject(TProcessItem.create(PO_EDLEMAN_SHOW,nil));

      end;

      PO_EDITOR_LL_CANCEL : begin
        aMaster.ProcessObject(TProcessItem.create(PO_EDLEMAN_HIDE,nil));
        if not aEditing then
          aMaster.ProcessObject(TProcessItem.create(PO_PROJECT_DELETE_LOG_LAYER,
            TString.Create('log0')));
      end;

      PO_EDITOR_LL_LOAD_FRM : begin
        form := TformLL.Create(nil);
        setComponent(form.frame AS TFrameLL);
        aFrame.Manager := Self;
        aEditorFrame := form.TfEditor1;
        aEditorFrame.Manager := self;
        aEditing := true;
        aEditorFrame := form.TfEditor1;
        aEditorFrame.Manager := self;
        aFrame.txtName.Enabled := false;
        aFrame.txtName.Text := (paItem.Data AS TString).String_;
        item := aMaster.ProcessObject(TProcessItem.create(PO_SCENE_GET_ACTUAL_LEVEL, nil));
        if item.Data <> nil then
         begin
          level := TProcessingLevel(item.Data).Level;
          if level <> nil then
           begin
            aEditorFrame.LevelSize := level.SizeX;
            form.init;
            aMaster.ProcessObject(TProcessItem.create(PO_EDITOR_LL_SET_LEVEL, TProcessingLevel.Create(TProcessingLevel(item.Data).Level)));
            item := aMaster.ProcessObject(TProcessItem.create(PO_SCENE_GET_ID, nil));
            aMaster.ProcessObject(TProcessItem.create(PO_EDITOR_LL_SET_ID, TInteger.Create(TInteger(item.Data).Integer_)));
           end
          else
            raise ELLManager.Create('Error on level load');
         end;
        form.Show;
        Master.ProcessObject(TProcessItem.create(PO_EDLEMAN_SHOW,nil));
      end;

      PO_EDITOR_LL_CLOSE : begin
        aMaster.ProcessObject(TProcessItem.create(PO_EDLEMAN_HIDE,nil));
        aFrame.btnCancelClick(nil);
      end;

      PO_EDITOR_LL_SET_LEVEL: begin
       for phs in level.allObstacles do
        begin
          if phs is TPolygon then
           begin
             obst := TPolygonObstacle.Create;
             for j := 0 to TPolygon(phs).Points.Count - 1 do
             begin
               coord := TCoordinates(TPolygon(phs).Points[j]);
               obst.AddPoint(TVector3f.Create(coord.x, coord.y, 0));
             end;
           obst.ID := phs.ID;
           if phs.LogicalEntity = nil then
            obst.LogEntity:= false
           else obst.LogEntity:= true;
           coord:= TCoordinates(TPolygon(phs).Position);
           obst.Position:= TVector3f.Create(coord.X, coord.Y, 0);
           // obst.LogEntity:= false;
           aEditorFrame.Obstacles.Add(obst);
           aEditorFrame.AllObstacles.Add(obst);
           end;
        end;



       for log in level.AllLogicalEntities do
       begin
          if log.Shape is TPolygon then
           begin
             obst:= TPolygonObstacle.Create;
             case log.TypeLogic of
              ET_DOOR_TYPE: obst.Color.SetRGBA(0.66,0.78,2.23,0.5);
              ET_WALL_TYPE: obst.Color.SetRGBA(2.51,0.11,0.35,0.5);
              ET_STAIRS_TYPE: obst.Color.SetRGBA(0.28,1.64,0.85,0.5);
              ET_LIFT_TYPE: obst.Color.SetRGBA(2.42,2.37,0.28,0.5);
              ET_TURNIQUET_TYPE: obst.Color.SetRGBA(1.18,1.52,1.36,0.5);
              ET_SPAWN_TYPE: obst.Color.SetRGBA(2.43, 2.49, 0.21, 0.5);
              ET_SINK_TYPE: obst.Color.SetRGBA(0.65, 0.65, 0.65, 0.5);
              ET_WAYPOINT_TYPE: obst.Color.SetRGBA(0.64, 0, 0.64, 0.5);
             end;
               for j := 0 to TPolygon(log.Shape).Points.Count - 1 do
               begin
                 coord:= TCoordinates(TPolygon(log.Shape).Points[j]);
                 obst.AddPoint(TVector3f.Create(coord.X, coord.Y, 0));
               end;
               coord:= TCoordinates(TPolygon(log.Shape).Position);
               obst.Position:= TVector3f.Create(coord.X, coord.Y, 0);
               obst.Typ:= log.TypeLogic;
               obst.LogEntity:= true;
               obst.ID:= log.Id;
               aEditorFrame.LogObstacles.Add(obst);
               aEditorFrame.AllObstacles.Add(obst);
          end
       end;
      end;

      PO_EDITOR_LL_SET_ID : begin
        aEditorFrame.aEntityId := value.Integer_;
      end;

      PO_EDITOR_LL_SAVE : begin   // treba kontrolovat zmeny a podla toho insert, edit ...
      aMaster.ProcessObject(TProcessItem.create(PO_EDLEMAN_HIDE,nil));
      if not aEditing then begin
        aMaster.ProcessObject(TProcessItem.create(PO_TREE_INSERT_LOG_LAYER, TString.Create(aFrame.txtName.Text)));

        list := TProcessingList.Create;
        list.addParameter(TString.Create('log0'));
        list.addParameter(TString.Create(aFrame.txtName.Text));
        item := aMaster.ProcessObject(TProcessItem.create(PO_PROJECT_UPDATE_LOG_LAYER, list));
        aFrame.Success := true;
        if item.Code = PO_FAILURE then
         begin
           aFrame.Success := False;
           ShowMessage('Update not successful');
         end;
       end
      else
       begin
        aMaster.ProcessObject(TProcessItem.create(PO_PROJECT_SAVE_LOG_LAYER, TString.Create(aFrame.txtName.Text)));
        aFrame.Success := true;
       end;

      end
      else raise ELLManager.Create('not specified operation for TEditoLLManager : ' + IntToStr(paItem.Code));
    end;

    if (ret) then begin
      if (suc) then
        Result := TProcessItem.create(PO_SUCCESS, nil)
      else
        Result := TProcessItem.create(PO_FAILURE, nil);
    end
    else
      Result := nil;
end;


procedure TEditorLLManager.setComponent(paFrame: TFrameLL);
begin
  aFrame := paFrame;
end;

procedure TEditorLLManager.addPhysicalLayers(paMap: TList<TMapping>);
begin
end;

constructor TEditorLLManager.create(paMaster: TManager);
begin
  inherited Create(paMaster);
  aName := 'none';
//  aFrame := nil;
end;

end.
